
async def {{ name.lower_snake_case }}(self{% for param in params %}, {{ param.name.lower_snake_case }}{% endfor %}):
    """
 {{ indent(method_description, 1) }}

     {% if params -%}
     Parameters
     ----------
     {% for param in params -%}
     {{ param.name.lower_snake_case }} : {{ param.type_info.name }}
         {{ param.description }}
     {% endfor -%}
     {% endif -%}

     Yields
     -------
     {{ return_name.lower_snake_case }} : {{ return_type.name }}
         {{ return_description }}
     {% if has_result -%}
     Raises
     ------
     {{ plugin_name.upper_camel_case }}Error
         If the request fails. The error contains the reason for the failure.
     {%- endif %}
    """

    request = {{ plugin_name.lower_snake_case }}_pb2.Subscribe{{ name.upper_camel_case }}Request()
    {% for param in params %}
        {%- if param.type_info.is_primitive -%}
    request.{{ param.name.lower_snake_case }} = {{ param.name.lower_snake_case }}
        {%- else -%}
            {% if param.type_info.is_repeated %}
    rpc_elems_list = []
    for elem in {{ param.name.lower_snake_case }}:
                {% if param.type_info.is_enum %}
        rpc_elems_list.append(elem.translate_to_rpc())
                {% else %}
        rpc_elem = {{ plugin_name.lower_snake_case }}_pb2.{{ param.type_info.inner_name }}()
        elem.translate_to_rpc(rpc_elem)
        rpc_elems_list.append(rpc_elem)
                {% endif %}
    request.{{ param.name.lower_snake_case }}.extend(rpc_elems_list)
            {% elif param.type_info.is_enum %}
    request.{{ param.name.lower_snake_case }} = {{ param.name.lower_snake_case }}.translate_to_rpc()
            {% else %}
    {{ param.name.lower_snake_case }}.translate_to_rpc(request.{{ param.name.lower_snake_case }})
            {% endif %}
        {% endif %}
    {% endfor -%}
    {{ name.lower_snake_case }}_stream = self._stub.Subscribe{{ name.upper_camel_case }}(request)

    try:
        async for response in {{ name.lower_snake_case }}_stream:
            {% if has_result %}
            result = self._extract_result(response)

            success_codes = [{{ plugin_name.upper_camel_case }}Result.Result.SUCCESS]
            if 'NEXT' in [return_code.name for return_code in {{ plugin_name.upper_camel_case }}Result.Result]:
                success_codes.append({{ plugin_name.upper_camel_case }}Result.Result.NEXT)

            if result.result not in success_codes:
                raise {{ plugin_name.upper_camel_case }}Error(result, "{{ name.lower_snake_case }}()"{% for param in params %}, {{ param.name.lower_snake_case }}{% endfor %})

            if result.result == {{ plugin_name.upper_camel_case }}Result.Result.SUCCESS:
                {{ name.lower_snake_case }}_stream.cancel();
                return
            {% endif %}

        {% if not return_type %}
            yield None
        {%- elif return_type.is_primitive %}
            yield response.{{ return_name.lower_snake_case }}
        {%- elif not return_type.is_primitive and not return_type.is_repeated %}
            yield {{ return_type.name }}.translate_from_rpc(response.{{ return_name.lower_snake_case }})
        {%- elif not return_type.is_primitive and return_type.is_repeated %}
            yield list(map(lambda x : {{ return_type.inner_name }}.translate_from_rpc(x), response.{{ return_name.lower_snake_case }}))
        {%- endif %}
    finally:
        {{ name.lower_snake_case }}_stream.cancel()
